package cn.good.yan.controller;

import cn.good.yan.entity.Order;
import cn.good.yan.pojo.CommonResult;
import cn.good.yan.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;

/**
 * 订单服务
 *
 * @author shengren.yan
 * @create 2024-02-22
 */
@RestController
@RequestMapping("/t1")
@Slf4j
public class OrderController {

    @Autowired
    private OrderService orderService;

    /**
     * 创建订单，参数：id 代表减多少库存和金额
     * 模拟演示： 分别启动 服务2003/2001/2003 这台服务、nacos 、分布式事务服务端
     * 演示1：
     * 请求 http://localhost:2001/t1/order/2  - 正常访问  订单创建成功 - 产品库存扣减成功 - 账户的金额扣减成功
     * 演示2：账户服务，手动制造异常
     * 请求 http://localhost:2001/t1/order/2  - 正常访问  订单创建成功 - 产品库存扣减成功 - 账户的金额扣减失败（应该全局都失败）
     * 演示3： @Transactional(rollbackFor = Exception.class)  本地事务 + 手动制造异常
     * 请求 http://localhost:2001/t1/order/2  - 正常访问  订单创建失败 - 产品库存扣减成功 - 账户的金额扣减失败（应该全局都失败）
     * 演示4：@GlobalTransactional(rollbackFor = Exception.class) 分布式事务 + 手动制造异常
     * 请求 http://localhost:2001/t1/order/2  - 正常访问  订单创建成功 - 产品库存扣减成功 - 账户的金额扣减失败（应该全局都失败）
     */
    @GetMapping("/order/{id}")
    public CommonResult create(@PathVariable("id") Integer id) {
        Order order = new Order();
        order.setUserId(1l);
        order.setProductId(1l);
        // 购买 数量个数
        order.setCount(id);
        // 购买 数量金额
        order.setMoney(new BigDecimal(id * 10));
        orderService.create(order);
        return new CommonResult(200, "订单创建成功!");
    }

    /**
     * 创建订单，参数：id 代表减多少库存和金额
     * 演示：
     * AT 模式 - 默认的，第一阶段，一次一提交， 第二阶段，正常就删除快照记录、有问题回滚
     * XA 模式 - 分阶段提交，第一阶段，不提交事务，第二阶段 - 最后提交事务
     *          需要在DataSourceProxyConfig，配置 XA模式、配置文件：data-source-proxy-mode: XA
     * TCC 模式 - 逻辑鞋在 Storage服务里，进行手动处理 、 回滚数据，需要手动处理：接口幂等性、空回滚现象
     *          不依赖与数据源
     * Saga 模式 一般不使用，会出现脏数据。适合场景（第三方服务接口）
     *
     * -- 账户
     * SELECT id, user_id as '用户id', total as '总额度', used as '已用余额', residue as '剩余可用额度'
     * FROM t_account;
     *
     * -- 订单
     * SELECT id,user_id '用户id', product_id as '产品id', count as '数量', money as '金额',
     * status as '订单状态'
     * FROM t_order;
     *
     * -- 仓库
     * SELECT id, product_id as '产品id', total as '总库存', used as '已用库存', residue '剩余库存'
     * FROM t_storage;
     * -- 仓库 - 回滚冻结数据记录
     * SELECT * FROM s_sto_tbl;
     *
     * 分别请求 该路径：
     *      正常数据     http://localhost:2001/t1/mood/2
     *      异常需要回滚：http://localhost:2001/t1/mood/15
     */
    @GetMapping("/mood/{id}")
    public CommonResult mood(@PathVariable("id") Integer id) {
        Order order = new Order();
        order.setUserId(1l);
        order.setProductId(1l);
        // 购买 数量个数
        order.setCount(id);
        // 购买 数量金额
        order.setMoney(new BigDecimal(id * 10));
        orderService.create(order);
        return new CommonResult(200, "订单创建成功!");
    }

}
